package hc.bre.cmn;

import java.util.LinkedList;
import java.util.List;

public interface ITreeNode<T extends ITreeNode<T>> extends IDetailList<T>, IId {
	@SuppressWarnings("unchecked")
	default T find(int id) {
		if (this.getId() == id)
			return (T) this;

		return findFrom(id, getList());
	};

	@SuppressWarnings("unchecked")
	default List<T> routeOf(int id) {
		LinkedList<T> lst = new LinkedList<T>();
		lst.add((T) this);
		return routeFrom(id, lst);
	};

	static <T extends ITreeNode<T>> T findFrom(int id, List<T> list) {
		if (list == null)
			return null;

		for (T it : list) {
			if (it.getId() == id)
				return it;
			else {
				T finded = ITreeNode.<T>findFrom(id, it.getList());
				if (finded != null)
					return finded;
			}
		}

		return null;
	}

	static <T extends ITreeNode<T>> boolean routeFrom(int id, List<T> lst, LinkedList<T> route) {
		if (lst == null)
			return false;

		for (T it : lst) {
			if (it.getId() == id) {
				route.addLast(it);
				return true;

			} else {
				route.addLast(it);

				if (routeFrom(id, it.getList(), route))
					return true;

				route.removeLast();
			}
		}
		;

		return false;
	}

	static <T extends ITreeNode<T>> List<T> routeFrom(int id, List<T> list) {
		LinkedList<T> stack = new LinkedList<T>();
		routeFrom(id, list, stack);
		return stack;
	}
}
